JS30 Day 11 筆記


Posted by GL on 2023-05-23

功能

用 HTML video 進行播放、暫停、快轉、倒退、音量與播放速度的控制

Demo

播放

step 1 : 獲取相關的元素

/* Get Our Elements */
const player = document.querySelector('.player') //最外層的容器
const video = player.querySelector('.viewer') // 影片
const progress = player.querySelector('.progress') // 進度條
const progressBar = player.querySelector('.progress__filled') // 進度條填色部分
const toggle = player.querySelector('.toggle') // 播放按鈕
const ranges = player.querySelectorAll('.player__slider') // 音量/ 播放速度 控制桿

const skipButtons = player.querySelectorAll('[data-skip]') // 快轉/ 倒退 按鈕

// 如果不用上面的 data-* 選取器的話,可以試著在 html 上加 class name
//const skipButtons = player.querySelectorAll('.skip')

step 2 : 監聽滑鼠點擊與播放與否的事件

/* 播放相關 */

// 影片被點擊時,執行 togglePlay
video.addEventListener('click', togglePlay)

// 由於有兩種情況操控影片是否播放,1. 透過點擊影片; 2.切換播放鈕來
// 因此與其在上述兩種情況放監聽器,
// 倒不如只透過影片播放或暫停的狀態,執行 updateButton(),改變 icon 
video.addEventListener('play',updateButton)
video.addEventListener('pause',updateButton)


// 播放按鈕被點擊時,執行 togglePlay
toggle.addEventListener('click', togglePlay)

step 3 : 建立函式 togglePlay 與 updateButton


// 開始或暫停:利用三元運算子判斷 video 的方法
function togglePlay(){
  // 下面程式相當於 video.paused ? video.play():video.pause()
  const isPlay = video.paused ? 'play' : 'pause'
  video[isPlay]() 
}

// 開始或暫停:上述方法也可寫為
// function togglePlay(){
//   if(video.paused){
//     video.play()
//   }else{
//     video.pause()
//   }
// }

// 判斷影片在播放或是暫停,更換相應 icon
function updateButton(){
  const icon = this.paused ? '►' : '❚ ❚'
  toggle.textContent = icon
}

進度條

step 1 : 監聽滑鼠點擊與滑鼠移動的事件

/* 播放進度條相關 */

// 影片播放時間更新時,執行 handleProgress()
video.addEventListener('timeupdate', handleProgress)

// 建立變數 mousedown,控制滑鼠的點擊與移動事件
let mousedown = false
progress.addEventListener('mousedown', () => mousedown = true)
progress.addEventListener('mouseup', () => mousedown = false)

// 滑鼠點擊並且移動時,執行 scrub()
// && => 當 mousedown 為 true 時,&& 後面才執行
// || => 當 || 前面為 false 時, || 後面才執行
progress.addEventListener('mousemove', (e) => mousedown && scrub(e))

// 滑鼠點擊時,執行 scrub()
progress.addEventListener('click', scrub)

step 2 : 建立進度條相關的函式 handleProgress 與 scrub

// 顯示進度條的長度
function handleProgress(){
  // 找出當前影片播放的長度佔影片總長度的比例
  // (現在播放的時間位置 / 影片時間總長) * 100 
  const percent = (video.currentTime / video.duration ) * 100

  // 改變 style,進度條顯示相應的比例的長度
  progressBar.style.flexBasis = `${percent}%`
}

// 滑鼠拖拉進度條到指定的時間位置
// offsetX => event 元素的水平位置
// offsetWidth => 元素的長度
function scrub(e){
  // 拖拉後所在的影片時間點
  // (拖拉的長度 / 進度條的總長) * 影片總共的時間
  const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;

  // 將影片播放的位置改為拖拉後的時間點
  video.currentTime = scrubTime;
}

快進 / 倒退 按鈕

step 1 : 監聽滑鼠點擊的事件

/* 快進、回退的按鈕 */

//將每個 skip 按鈕掛上監聽器,當點擊這些按鈕時,執行 skip()
skipButtons.forEach(button => button.addEventListener('click', skip))

step 2 : 建立函式 skip

// 快進 / 倒退 影片
function skip(){
  // 用 dataset.* 取得 html 中 date-* 的值
  // 更改的時間 = 當前影片的時間 + 要快進 / 倒退 的秒數
  video.currentTime += parseFloat(this.dataset.skip)
}

音量大小 / 播放速度 控制桿

step 1 : 監聽控制桿改變以及滑鼠拖曳的事件

/* 音量與速度操控桿相關 */

// 將每個操控桿掛上監聽器,當操控桿發生變化的當下或滑鼠拖曳時,執行 handleRangeUpdate()
ranges.forEach(range => range.addEventListener('chanege', handleRangeUpdate))
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate))

step 2 : 建立函式 handleRangeUpdate

// 將 html 的 name 帶入 video 屬性中,並且更新其值 
// name 有 volumn 、 playbackRate 這兩種屬性
function handleRangeUpdate(){
  video[this.name] = this.value
}

Javascript

HTML Video

<video controls width="250"></video>

// controls => 預設的播放器
// width => 播放器寬度
// height => 播放器高度
// src => 要嵌入頁面的視頻 URL
// loop => 連續播放


// HTML Video 同時繼承了 HTMLMediaElement 的方法與屬性

// play();  播放影片
// pause(); 暫停影片
// paused;  暫停狀態
// muted;   是否靜音
// volume;  影片音量 
// playbackRate;  播放速度
// currentTime;   影片播放到的時間
// duration;      影片時間總長

參考資料:


#JS 30







Related Posts

JavaScript 核心 - Event Loop

JavaScript 核心 - Event Loop

[21] 強制轉型 - ToNumber、ToPrimitive、StringNumericLiteral、NonDecimalIntegerLiteral

[21] 強制轉型 - ToNumber、ToPrimitive、StringNumericLiteral、NonDecimalIntegerLiteral

[新手村系列] Markdown 和 HTML 基礎語法教學

[新手村系列] Markdown 和 HTML 基礎語法教學


Comments